package websocket

import (
	"encoding/json"
	"errors"
	"strconv"
	"sync"
)

var (
	NoFindUser = errors.New("无法找到用户")
)

const (
	Group = "group:"
)

type MessageText struct {
	Msg     string `json:"msg"`
	From    string `json:"from"`
	To      string `json:"to"`
	Group   bool   `json:"group"`
	All     bool   `json:"all"`
	GroupId string `json:"group_id"`
	UserId  string `json:"user_id"`
}

func (m MessageText) GetConnectName() string {
	return m.From + "-" + m.To
}
func (m MessageText) GetConnectNameT() string {
	return m.To + "-" + m.From
}
func (m MessageText) GetRedisConnectName() string {
	form, _ := strconv.ParseInt(m.From, 10, 64)
	to, _ := strconv.ParseInt(m.To, 10, 64)
	if form > to {
		return m.GetConnectName()
	}
	return m.GetConnectNameT()
}
func NewMessageText(msg, from, to, groupID, userID string, group, all bool) *MessageText {
	return &MessageText{
		Msg:     msg,
		From:    from,
		To:      to,
		Group:   group,
		All:     all,
		GroupId: groupID,
		UserId:  userID,
	}
}
func (m MessageText) GetMessage() (res []byte, err error) {
	res, err = json.Marshal(m)
	if err != nil {
		return
	}
	return
}

// ----
var web *WebServerInfo
var AllPeopleServer map[string]*WebServerInfo

type WebServerInfo struct {
	Username     string
	OnLinePeople int
	LeavePeople  int
	UserIDs      sync.Map // map [form-to:cID]
	*Server
}

func GetWebServer() *WebServerInfo {
	return web
}
func NewWebServerInfo(username string, OnLinePeople int, LeavePeople int) {
	web = &WebServerInfo{
		Username:     username,
		OnLinePeople: OnLinePeople,
		LeavePeople:  LeavePeople,
		UserIDs:      sync.Map{},
		Server: New(Config{
			ReadBufferSize:  1024,
			WriteBufferSize: 1024,
		})}
}

// UserClose 用户退出
func (w WebServerInfo) UserClose(userID string) (re bool) {
	re = false
	//获得当前的连接ID
	connID, ok := w.UserIDs.Load(userID)
	if ok {
		if connIDStr, ok := connID.(string); ok {
			//退出所有房间
			w.Server.LeaveAll(connIDStr)
		}
	}
	//删除用户
	w.UserIDs.Delete(userID)
	w.OnLinePeople--
	w.LeavePeople++
	return true
}

// UserConnect 用户连接
func (w WebServerInfo) UserConnect(UserID, ConnID string, room []string) (re bool) {
	re = false
	//添加用户
	w.UserIDs.Store(UserID, ConnID)
	//向房间添加用户
	for _, name := range room {
		w.Server.join(name, ConnID)
	}
	w.OnLinePeople++
	w.LeavePeople--
	return true
}

// UserSendMsg 用户发送消息
func (w WebServerInfo) UserSendMsg(val *MessageText) (err error) {
	byteData, err := json.Marshal(val)
	if err != nil {
		return err
	}
	//获得用户的连接
	connID, ok := w.UserIDs.Load(val.GetConnectName())
	if !ok {
		err = NoFindUser
		return
	}
	connIDStr, ok := connID.(string)
	if !ok {
		return
	}
	formConn := w.Server.GetConnection(connIDStr)
	//如果是发送到全部
	if val.All {
		formConn.To(All).EmitMessage(byteData)
		return
	}
	//如果是发送到组
	if val.Group {
		//获得组的id
		Peoples := w.GetConnectionsByRoom(Group + val.GroupId)
		cID, _ := w.UserIDs.Load(val.GetConnectName())
		cIdStr, _ := cID.(string)
		for _, people := range Peoples {
			if people.ID() == cIdStr {
				//不要重复给自己发
				continue
			}
			people.To(people.ID()).EmitMessage(byteData)
		}
		return
	}
	//如果发送到个人
	peopleID, ok := w.UserIDs.Load(val.GetConnectNameT())
	if !ok {
		err = NoFindUser
		return
	}
	peopleIDStr, ok := peopleID.(string)
	if !ok {
		return
	}
	//获得个人的连接
	peopleConn := w.GetConnection(peopleIDStr)
	peopleConn.To(peopleConn.ID()).EmitMessage(byteData)
	return
}
func (w WebServerInfo) UserSelfMsg(emit string, self Connection, msg []byte) {
	msgStr := string(msg)
	self.To(self.ID()).Emit(emit, msgStr)
	return
}
func (w WebServerInfo) UserSelfOldMsg(self Connection, msg []byte) {
	self.To(self.ID()).EmitMessage(msg)
}
